package org.liaohailong.victorlibrary.widget;

import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.View;

import androidx.recyclerview.widget.RecyclerView;

/**
 * Author: Victor
 * E-mail: liaohailong190@foxmail.com
 * Date: 2019/5/30 14:22
 * Description: 瀑布流布局->水平方向布局
 */
public class CascadeFlowLayoutManager extends RecyclerView.LayoutManager {
    private final Context mContext;
    private final int mSpanCount;
    private final SparseIntArray mLocation;
    private final SparseArray<Rect> mLayoutRect;

    public CascadeFlowLayoutManager(Context context, int spanCount) {
        mContext = context;
        mSpanCount = spanCount;
        mLocation = new SparseIntArray(mSpanCount);
        mLayoutRect = new SparseArray<>();
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (state.isPreLayout()) {
            return;
        }
        if (getItemCount() <= 0 || getWidth() <= 0 || getHeight() <= 0) {
            removeAndRecycleAllViews(recycler);
            return;
        }

        //计算瀑布流布局位置
        detachAndScrapAttachedViews(recycler);
        mLocation.clear();

        int columnWidth = getWidth() / mSpanCount;
        int itemCount = getItemCount();

        for (int i = 0; i < itemCount; i++) {
            View scrapView = recycler.getViewForPosition(i);
            addView(scrapView);
            measureChildWithMargins(scrapView, 0, 0);
            int itemWidth = getDecoratedMeasuredWidth(scrapView);
            int itemHeight = getDecoratedMeasuredHeight(scrapView);

            Rect viewRect = getViewRectByPosition(i);
            //确认水平位置
            int position = i % mSpanCount;
            int left = columnWidth * position;
            int right = left + columnWidth;
            viewRect.set(left, 0, right, 0);

            //确认垂直位置
            if (i < mSpanCount) {
                mLocation.put(i, itemHeight);
                viewRect.top = 0;
                viewRect.bottom = itemHeight;
            } else {
                Point lastBottom = getLastBottom(mLocation);
                Rect lastBottomRect = getViewRectByPosition(lastBottom.x);
                viewRect.left = lastBottomRect.left;
                viewRect.right = viewRect.left + columnWidth;
                viewRect.top = lastBottom.y;
                viewRect.bottom = viewRect.top + itemHeight;
                //更新最低锚点
                mLocation.put(lastBottom.x, viewRect.bottom);
            }
        }


        //开始布局
        detachAndScrapAttachedViews(recycler);
        for (int i = 0; i < itemCount; i++) {
            View scrapView = recycler.getViewForPosition(i);
            addView(scrapView);
            Rect rect = getViewRectByPosition(i);
            layoutDecoratedWithMargins(scrapView, rect.left, rect.top, rect.right, rect.bottom);
        }
    }

    private Point getLastBottom(SparseIntArray array) {
        int minValue = Integer.MAX_VALUE;
        int position = 0;
        for (int i = 0; i < array.size(); i++) {
            int value = array.valueAt(i);
            if (value < minValue) {
                minValue = value;
                position = i;
            }
        }
        return new Point(position, minValue);
    }

    private Rect getViewRectByPosition(int position) {
        Rect rect = mLayoutRect.get(position);
        if (rect == null) {
            rect = new Rect();
            mLayoutRect.put(position, rect);
        }
        return rect;
    }
}
